home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / jcl / jcl_long.h < prev    next >
C/C++ Source or Header  |  1999-11-04  |  16KB  |  586 lines

  1. // $Id: jcl_long.h,v 1.1 1999/11/04 18:48:04 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef jcl_long_INCLUDED
  11. #define jcl_ong_INCLUDED
  12.  
  13. #include <math.h>
  14. #include "jcl_bool.h"
  15. #include "jcl_int.h"
  16.  
  17. class Long;
  18. class ULong;
  19.  
  20. class BaseLong
  21. {
  22. protected:
  23.     union
  24.     {
  25.         double double_words;
  26.         u4 word[2];
  27.     } value;
  28.  
  29. public:
  30.  
  31. #ifdef BIGENDIAN
  32.     u4 &high_word() { return value.word[0]; }
  33.     u4 &low_word()  { return value.word[1]; }
  34. #else
  35.     u4 &low_word()  { return value.word[0]; }
  36.     u4 &high_word() { return value.word[1]; }
  37. #endif
  38.  
  39.     double &DoubleView() { return value.double_words; }
  40.  
  41.     inline BaseLong(u4 a, u4 b)
  42.     {
  43.         high_word() = a;
  44.         low_word() = b;
  45.     }
  46.  
  47.     inline BaseLong(u4 a)
  48.     {
  49.         high_word() = 0;
  50.         low_word() = a;
  51.     }
  52.  
  53.     inline BaseLong(i4 a)
  54.     {
  55.         low_word() = a;
  56.         //
  57.         // Since the carry is not guaranteed to ripple, we cannot use this code.
  58.         //
  59.         //        high_word() = a >> 31;
  60.         //
  61.         high_word() = (a < 0 ? 0xFFFFFFFF : 0x00000000);
  62.     }
  63.  
  64.     inline BaseLong (void) {}
  65.  
  66.     BaseLong  operator+  (BaseLong); // binary addition
  67.     BaseLong  operator+  ();         // unary plus
  68.     BaseLong& operator+= (BaseLong); // add and assign
  69.     BaseLong  operator++ (int);      // postfix increment
  70.     BaseLong  operator++ ();         // prefix increment
  71.  
  72.     BaseLong  operator-  (BaseLong); // binary subtraction
  73.     BaseLong  operator-  ();         // unary minus
  74.     BaseLong& operator-= (BaseLong); // subtract and assign
  75.     BaseLong  operator-- (int);      // postfix decrement
  76.     BaseLong  operator-- ();         // prefix decrement
  77.  
  78.     BaseLong  operator* (BaseLong);  // multiplication
  79.     BaseLong& operator*=(BaseLong);  // multiply and assign
  80.  
  81.     BaseLong  operator<< (BaseLong); // left shift
  82.     BaseLong& operator<<=(BaseLong); // left shift and assign
  83.  
  84.     bool      operator== (BaseLong); // equal
  85.     bool      operator!= (BaseLong); // not equal
  86.     bool      operator!  ();         // logical complement
  87.  
  88.     BaseLong  operator~  ();         // bitwise complement
  89.     BaseLong  operator^  (BaseLong); // bitwise XOR
  90.     BaseLong& operator^= (BaseLong); // bitwise XOR and assign
  91.     BaseLong  operator|  (BaseLong); // bitwise OR
  92.     BaseLong& operator|= (BaseLong); // bitwise OR and assign
  93.     BaseLong  operator&  (BaseLong); // bitwise AND
  94.     BaseLong& operator&= (BaseLong); // bitwise AND and assign
  95.  
  96.     bool      operator&& (BaseLong); // logical AND (not short-circuit)
  97.     bool      operator|| (BaseLong); // logical OR (not short circuit)
  98.  
  99.     static void divide(BaseLong, BaseLong, BaseLong &, BaseLong &);
  100.  
  101.     operator Long();                 // Cast to Long
  102.     operator ULong();                // Cast to ULong
  103. };
  104.  
  105.  
  106. class Long : public BaseLong
  107. {
  108. public:
  109.  
  110.     inline Long (u4 a, u4 b) : BaseLong (a, b) {}
  111.     inline Long (u4 a) : BaseLong (a) {}
  112.     inline Long (i4 a) : BaseLong (a) {}
  113.     inline Long (void) : BaseLong () {}
  114.     inline Long (double);
  115.  
  116.     Long  operator/  (Long); // divide
  117.     Long& operator/= (Long); // divide and assign
  118.  
  119.     Long  operator%  (Long); // modulus
  120.     Long& operator%= (Long); // modulus and assign
  121.  
  122.     Long  operator>> (Long); // right shift
  123.     Long& operator>>=(Long); // right shift and assign
  124.  
  125.     bool  operator<  (Long); // less-than
  126.     bool  operator>  (Long); // greater-than
  127.     bool  operator<= (Long); // less-than or equal
  128.     bool  operator>= (Long); // greater-than or equal
  129.  
  130.     double Double();         // convert Long value to a double value
  131.     void String(char *);     // convert Long value to its character string representation
  132. };
  133.  
  134.  
  135. class ULong : public BaseLong
  136. {
  137. public:
  138.  
  139.     inline ULong (u4 a, u4 b) : BaseLong (a, b) {}
  140.     inline ULong (u4 a) : BaseLong (a) {}
  141.     inline ULong (i4 a) : BaseLong (a) {}
  142.     inline ULong (void) : BaseLong () {}
  143.     inline ULong (double);
  144.  
  145.     ULong  operator/  (ULong); // divide
  146.     ULong& operator/= (ULong); // divide and assign
  147.  
  148.     ULong  operator%  (ULong); // modulus
  149.     ULong& operator%= (ULong); // modulus and assign
  150.  
  151.     ULong  operator>> (ULong); // right shift
  152.     ULong& operator>>=(ULong); // right shift and assign
  153.  
  154.     bool   operator<  (ULong); // less-than
  155.     bool   operator>  (ULong); // greater-than
  156.     bool   operator<= (ULong); // less-than or equal
  157.     bool   operator>= (ULong); // greater-than or equal
  158.  
  159.     double Double();           // convert Long value to a double value
  160.     void String(char *);       // convert Long value to its character string representation
  161. };
  162.  
  163.  
  164. inline BaseLong::operator Long()
  165. {
  166.     return Long(high_word(), low_word());
  167. }
  168.  
  169. inline BaseLong::operator ULong()
  170. {
  171.     return ULong(high_word(), low_word());
  172. }
  173.  
  174. inline bool BaseLong::operator== (BaseLong op)
  175. {
  176.     return ((high_word() == op.high_word()) && (low_word() == op.low_word()));
  177. }
  178.  
  179. inline bool BaseLong::operator!= (BaseLong op)
  180. {
  181.     return ((high_word() != op.high_word()) || (low_word() != op.low_word()));
  182. }
  183.  
  184. inline bool BaseLong::operator!()
  185. {
  186.     return (*this == 0);
  187. }
  188.  
  189. inline BaseLong BaseLong::operator~()
  190. {
  191.     return BaseLong(~high_word(), ~low_word());
  192. }
  193.  
  194. inline BaseLong BaseLong::operator^ (BaseLong op)
  195. {
  196.     return BaseLong(high_word() ^ op.high_word(), low_word() ^ op.low_word());
  197. }
  198.  
  199. inline BaseLong& BaseLong::operator^= (BaseLong op)
  200. {
  201.     *this = *this ^ op;
  202.     return *this;
  203. }
  204.  
  205. inline BaseLong BaseLong::operator| (BaseLong op)
  206. {
  207.     return BaseLong(high_word() | op.high_word(), low_word() | op.low_word());
  208. }
  209.  
  210. inline BaseLong& BaseLong::operator|= (BaseLong op)
  211. {
  212.     *this = *this | op;
  213.     return *this;
  214. }
  215.  
  216. inline BaseLong BaseLong::operator& (BaseLong op)
  217. {
  218.     return BaseLong(high_word() & op.high_word(), low_word() & op.low_word());
  219. }
  220.  
  221. inline BaseLong& BaseLong::operator&= (BaseLong op)
  222. {
  223.     *this = *this & op;
  224.     return *this;
  225. }
  226.  
  227. inline bool BaseLong::operator&& (BaseLong op)
  228. {
  229.     return (*this != 0) && (op != 0);
  230. }
  231.  
  232. inline bool BaseLong::operator|| (BaseLong op)
  233. {
  234.     return (*this != 0) || (op != 0);
  235. }
  236.  
  237. inline BaseLong BaseLong::operator<< (BaseLong op)
  238. {
  239.     u4 n = op.low_word(); // Always treat this value as positive, since negative values are not allowed
  240.  
  241.     //
  242.     // Note that this function assumes that for two 32-bit integers
  243.     // x << y, where y = 0, is well-defined and that the result is
  244.     // the value x. This is true in Ansi-C and C++ but not true in
  245.     // old versions of C (See Kernighan and Ritchie).
  246.     // Note also that if y >= 32 then the result is unpredictable. On Aix,
  247.     // xlC will produce the result 0(good!) whereas on windows the Microsoft
  248.     // compiler produces the value of x(very bad !).
  249.     //
  250.     return (n < 32 ? BaseLong((high_word() << n) | (low_word() >> (32 - n)), low_word() << n)
  251.                    : BaseLong(low_word() << (n - 32), 0));
  252. }
  253.  
  254. inline BaseLong& BaseLong::operator<<= (BaseLong op)
  255. {
  256.     *this = *this << op;
  257.     return *this;
  258. }
  259.  
  260. inline BaseLong BaseLong::operator+ (BaseLong op)
  261. {
  262.     u4 ushort1 = (low_word() & 0xFFFF) + (op.low_word() & 0xFFFF),
  263.        ushort2 = (ushort1 >> 16) + (low_word() >> 16) + (op.low_word() >> 16),
  264.        ushort3 = (ushort2 >> 16) + (high_word() & 0xFFFF) + (op.high_word() & 0xFFFF),
  265.        ushort4 = (ushort3 >> 16) + (high_word() >> 16) + (op.high_word() >> 16);
  266.  
  267.     return BaseLong((ushort3 & 0xFFFF) | (ushort4 << 16), (ushort1 & 0xFFFF) | (ushort2 << 16));
  268. }
  269.  
  270. inline BaseLong& BaseLong::operator+= (BaseLong op)
  271. {
  272.     *this = *this + op;
  273.     return *this;
  274. }
  275.  
  276. inline BaseLong BaseLong::operator++ (int dummy)
  277. {
  278.     BaseLong temp = *this;
  279.     *this += 1;
  280.     return temp;
  281. }
  282.  
  283. inline BaseLong BaseLong::operator++ ()
  284. {
  285.     *this += 1;
  286.     return *this;
  287. }
  288.  
  289. inline BaseLong BaseLong::operator- ()
  290. {
  291.     return ~(*this) + 1;
  292. }
  293.  
  294. inline BaseLong BaseLong::operator- (BaseLong op)
  295. {
  296.     return *this + (-op);
  297. }
  298.  
  299. inline BaseLong& BaseLong::operator-= (BaseLong op)
  300. {
  301.     *this = *this - op;
  302.     return *this;
  303. }
  304.  
  305. inline BaseLong BaseLong::operator-- (int dummy)
  306. {
  307.     BaseLong temp = *this;
  308.     *this -= 1;
  309.     return temp;
  310. }
  311.  
  312. inline BaseLong BaseLong::operator-- ()
  313. {
  314.     *this -= 1;
  315.     return *this;
  316. }
  317.  
  318. inline BaseLong BaseLong::operator* (BaseLong op)
  319. {
  320.     u4 x0 = this -> low_word()   & 0xFFFF,
  321.        x1 = this -> low_word()  >> 16,
  322.        x2 = this -> high_word()  & 0xFFFF,
  323.        x3 = this -> high_word() >> 16;
  324.  
  325.     u4 y0 = op.low_word()   & 0xFFFF,
  326.        y1 = op.low_word()  >> 16,
  327.        y2 = op.high_word()  & 0xFFFF,
  328.        y3 = op.high_word() >> 16;
  329.  
  330.     return (BaseLong(0, x0 * y0)) +
  331.            (BaseLong(0, x0 * y1) << (1 << 4)) +
  332.            (BaseLong(0, x0 * y2) << (2 << 4)) +
  333.            (BaseLong(0, x0 * y3) << (3 << 4)) +
  334.  
  335.            (BaseLong(0, x1 * y0) << (1 << 4)) +
  336.            (BaseLong(0, x1 * y1) << (2 << 4)) +
  337.            (BaseLong(0, x1 * y2) << (3 << 4)) +
  338.            (BaseLong(0, x1 * y3) << (4 << 4)) +
  339.  
  340.            (BaseLong(0, x2 * y0) << (2 << 4)) +
  341.            (BaseLong(0, x2 * y1) << (3 << 4)) +
  342.            (BaseLong(0, x2 * y2) << (4 << 4)) +
  343.            (BaseLong(0, x2 * y3) << (5 << 4)) +
  344.  
  345.            (BaseLong(0, x3 * y0) << (3 << 4)) +
  346.            (BaseLong(0, x3 * y1) << (4 << 4)) +
  347.            (BaseLong(0, x3 * y2) << (5 << 4)) +
  348.            (BaseLong(0, x3 * y3) << (6 << 4));
  349. }
  350.  
  351. inline BaseLong& BaseLong::operator*= (BaseLong op)
  352. {
  353.     *this = *this * op;
  354.     return *this;
  355. }
  356.  
  357. inline Long Long::operator/ (Long op)
  358. {
  359.     bool negative_dividend = high_word() & 0x80000000,
  360.          negative_divisor  = op.high_word() & 0x80000000;
  361.  
  362.     BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
  363.              b = (negative_divisor  ? -(op)    : (BaseLong) op),
  364.              quotient,
  365.              remainder;
  366.  
  367.     divide(a, b, quotient, remainder);
  368.  
  369.     return (negative_dividend ^ negative_divisor ? -quotient : quotient);
  370. }
  371.  
  372. inline Long& Long::operator/= (Long op)
  373. {
  374.     *this = *this / op;
  375.     return *this;
  376. }
  377.  
  378. inline Long Long::operator% (Long op)
  379. {
  380.     bool negative_dividend = high_word() & 0x80000000,
  381.          negative_divisor  = op.high_word() & 0x80000000;
  382.  
  383.     BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
  384.              b = (negative_divisor  ? -(op)    : (BaseLong) op),
  385.              quotient,
  386.              remainder;
  387.  
  388.     divide(a, b, quotient, remainder);
  389.  
  390.     return (negative_dividend ? -remainder : remainder);
  391. }
  392.  
  393. inline Long& Long::operator%= (Long op)
  394. {
  395.     *this = *this % op;
  396.     return *this;
  397. }
  398.  
  399. inline Long Long::operator>> (Long op)
  400. {
  401.     u4 n = op.low_word(); // Always treat this value as positive, since negative values are not allowed
  402.  
  403.     //
  404.     // Note that this function assumes that for two 32-bit integers
  405.     // x >> y, where y = 0, is well-defined and that the result is
  406.     // the value x. This is true in Ansi-C and C++ but not true in
  407.     // old versions of C (See Kernighan and Ritchie).
  408.     //
  409.     // Note also that if y >= 32 then the result is unpredictable. The xlC compiler
  410.     // on Aix will produce the result 0(good!) whereas on windows the Microsoft
  411.     // C++ compiler produces the value of x(very bad !).
  412.     //
  413.     // Finally, note that the right-shitfting of the high_word is not guaranteed
  414.     // to ripple the carry bit. Whether or not the carry-bit is rippled is
  415.     // implementation-dependent. Therefore, this implementation is designed to
  416.     // shift the "long" quantity in a similar manner as the system (compiler + environement)
  417.     // used to compile it would shift a 32-bit signed integer.
  418.     //
  419.     return (n < 32 ? Long(((i4) high_word()) >> n, (high_word() << (32 - n)) | (low_word() >> n))
  420.                    : Long(((i4) high_word()) >> 31, ((i4) high_word()) >> (n - 32)));
  421. }
  422.  
  423. inline Long& Long::operator>>= (Long op)
  424. {
  425.     *this = *this >> op;
  426.     return *this;
  427. }
  428.  
  429. inline bool Long::operator< (Long op)
  430. {
  431.     return (high_word() == op.high_word() ? low_word() < op.low_word() : (i4) high_word() < (i4) op.high_word());
  432. }
  433.  
  434. inline bool Long::operator<= (Long op)
  435. {
  436.     return (high_word() == op.high_word() ? low_word() <= op.low_word() : (i4) high_word() <= (i4) op.high_word());
  437. }
  438.  
  439. inline bool Long::operator> (Long op)
  440. {
  441.     return (high_word() == op.high_word() ? low_word() > op.low_word() : (i4) high_word() > (i4) op.high_word());
  442. }
  443.  
  444. inline bool Long::operator>= (Long op)
  445. {
  446.     return (high_word() == op.high_word() ? low_word() >= op.low_word() : (i4) high_word() >= (i4) op.high_word());
  447. }
  448.  
  449. inline Long::Long(double a) : BaseLong (0,0)
  450. {
  451.     double b = floor(a < 0.0 ? -a : a);
  452.     Long multiplier = 1;
  453.  
  454.     while (b > 0.0)
  455.     {
  456.         *this += (multiplier * (int) fmod(b, 10));
  457.         b /=  10.0;
  458.         multiplier *= 10;
  459.     }
  460.  
  461.     if (a < 0.0)
  462.         *this = -(*this);
  463. }
  464.  
  465. inline double Long::Double()
  466. {
  467.     double value = 0.0;
  468.     Long num = *this;
  469.     double multiplier = 1.0;
  470.  
  471.     while (num > 0)
  472.     {
  473.         value += (multiplier * (num % 10).low_word());
  474.         num /= 10;
  475.         multiplier *= 10.0;
  476.     }
  477.  
  478.     return value;
  479. }
  480.  
  481. inline ULong ULong::operator/ (ULong op)
  482. {
  483.     BaseLong quotient,
  484.              remainder;
  485.  
  486.     divide(*this, op, quotient, remainder);
  487.  
  488.     return quotient;
  489. }
  490.  
  491. inline ULong& ULong::operator/= (ULong op)
  492. {
  493.     *this = *this / op;
  494.     return *this;
  495. }
  496.  
  497. inline ULong ULong::operator% (ULong op)
  498. {
  499.     BaseLong quotient,
  500.              remainder;
  501.  
  502.     divide(*this, op, quotient, remainder);
  503.  
  504.     return remainder;
  505. }
  506.  
  507. inline ULong& ULong::operator%= (ULong op)
  508. {
  509.     *this = *this % op;
  510.     return *this;
  511. }
  512.  
  513. inline ULong ULong::operator>> (ULong op)
  514. {
  515.     u4 n = op.low_word(); // Always treat this value as positive, since negative values are not allowed
  516.  
  517.     //
  518.     // Note that this function assumes that for two 32-bit integers
  519.     // x >> y, where y = 0, is well-defined and that the result is
  520.     // the value x. This is true in Ansi-C and C++ but not true in
  521.     // old versions of C (See Kernighan and Ritchie).
  522.     // Note also that if y >= 32 then the result is unpredictable. On Aix,
  523.     // xlC will produce the result 0(good!) whereas on windows the Microsoft
  524.     // compiler produces the value of x(very bad !).
  525.     //
  526.     return (n < 32 ? ULong(high_word() >> n, (high_word() << (32 - n)) | (low_word() >> n))
  527.                    : ULong(0, high_word() >> (n - 32)));
  528. }
  529.  
  530. inline ULong& ULong::operator>>= (ULong op)
  531. {
  532.     *this = *this >> op;
  533.     return *this;
  534. }
  535.  
  536. inline bool ULong::operator< (ULong op)
  537. {
  538.     return (high_word() == op.high_word() ? low_word() < op.low_word() : high_word() < op.high_word());
  539. }
  540.  
  541. inline bool ULong::operator<= (ULong op)
  542. {
  543.     return (high_word() == op.high_word() ? low_word() <= op.low_word() : high_word() <= op.high_word());
  544. }
  545.  
  546. inline bool ULong::operator> (ULong op)
  547. {
  548.     return (high_word() == op.high_word() ? low_word() > op.low_word() : high_word() > op.high_word());
  549. }
  550.  
  551. inline bool ULong::operator>= (ULong op)
  552. {
  553.     return (high_word() == op.high_word() ? low_word() >= op.low_word() : high_word() >= op.high_word());
  554. }
  555.  
  556. inline ULong::ULong(double a) : BaseLong(0,0)
  557. {
  558.     double b = floor(a < 0.0 ? -a : a);
  559.     ULong multiplier = 1;
  560.  
  561.     while (b > 0.0)
  562.     {
  563.         *this += (multiplier * (int) fmod(b, 10));
  564.         b /= 10.0;
  565.         multiplier *= 10;
  566.     }
  567. }
  568.  
  569. inline double ULong::Double()
  570. {
  571.     double value = 0.0;
  572.     ULong num = *this;
  573.     double multiplier = 1.0;
  574.  
  575.     while (num > 0)
  576.     {
  577.         value += (multiplier * (num % 10).low_word());
  578.         num /= 10;
  579.         multiplier *= 10.0;
  580.     }
  581.  
  582.     return value;
  583. }
  584.  
  585. #endif
  586.